﻿using System;
using System.Web;
using umbraco.BusinessLogic;
using umbraco.interfaces;
using System.Xml;
using umbraco.IO;
using helper=umbraco.cms.businesslogic.packager.standardPackageActions.helper;

namespace uForum.PackageActions
{
    public class Add404Handler : IPackageAction
    {
        #region IPackageAction Members

        public string Alias()
        {
            return "uForum_Add404Handler";
        }

        public bool Execute(string packageName, XmlNode xmlData)
        {
            
            try
            {
                //Get attribute values
                string handlerAssembly = XmlHelper.GetAttributeValueFromNode(xmlData, "assembly");
                string handlerType = XmlHelper.GetAttributeValueFromNode(xmlData, "type");

                //Open the Umbraco Settings config file
                XmlDocument umbraco404HandlersFile = umbraco.xmlHelper.OpenAsXmlDocument(SystemFiles.NotFoundhandlersConfig);

                //Select scheduled tasks node from the settings file
                XmlNode handlersRootNode = umbraco404HandlersFile.SelectSingleNode("//NotFoundHandlers");

                //Create a new scheduled task node 
                XmlNode handlerNode = umbraco404HandlersFile.CreateElement("notFound");

                //Append addributes
                handlerNode.Attributes.Append(umbraco.xmlHelper.addAttribute(umbraco404HandlersFile, "assembly",
                                                                             handlerAssembly));
                handlerNode.Attributes.Append(umbraco.xmlHelper.addAttribute(umbraco404HandlersFile, "type", handlerType));

                //Append the new rewrite scheduled task to the Umbraco Settings config file
                handlersRootNode.InsertBefore(handlerNode,
                                              handlersRootNode.SelectSingleNode(
                                                  "//notFound[@assembly = 'umbraco' and @type = 'SearchForProfile']"));

                //Save the Umbraco Settings config file with the new Scheduled task
                umbraco404HandlersFile.Save(HttpContext.Current.Server.MapPath(SystemFiles.NotFoundhandlersConfig));

                //No errors so the result is true
                return true;
            }
            catch (Exception e)
            {
                Log.Add(LogTypes.Error, 0, "Add404Handler Action failed to install: " + e);

                return false;
            }
        }

        public XmlNode SampleXml()
        {
            const string sample = "<Action runat=\"install\" alias=\"Add404Handler\" assembly=\"myassemblyname\" type=\"myhandlertype\"></Action>";
            return helper.parseStringToXmlNode(sample);
        }

        public bool Undo(string packageName, XmlNode xmlData)
        {
            try
            {
                //Get alias to remove
                string handlerAssemblyAlias = XmlHelper.GetAttributeValueFromNode(xmlData, "assembly");
                string handlerTypeAlias = XmlHelper.GetAttributeValueFromNode(xmlData, "type");

                //Open the Umbraco Settings config file
                XmlDocument umbraco4040HanldersFile = umbraco.xmlHelper.OpenAsXmlDocument("/config/404handlers.config");

                //Select scheduled tasks root node from the settings file
                XmlNode handlersNode = umbraco4040HanldersFile.SelectSingleNode("//NotFoundHandlers");

                //Get the child node with the scheduled task we want to remove
                //Select the url rewrite rule by name from the config file
                XmlNode scheduledTaskNode =
                    handlersNode.SelectSingleNode("//notFound[@assembly = '" + handlerAssemblyAlias + "' and @type = '" +
                                                  handlerTypeAlias + "']");

                if (scheduledTaskNode != null)
                {
                    //Child node is not null, remove it
                    handlersNode.RemoveChild(scheduledTaskNode);

                    //Save the modified configuration file
                    umbraco4040HanldersFile.Save(HttpContext.Current.Server.MapPath("/config/404handlers.config"));
                }
                return true;
            }
            catch (Exception e)
            {
                Log.Add(LogTypes.Error, 0, "Add404Handler Action failed to uninstall: " + e);
                return false;
            }

        }

        #endregion
    }

    public class XmlHelper
    {
        /// <summary>
        /// Gets the value from an attribute or returns an empty string if it wasn't specified
        /// </summary>

        public static string GetAttributeValueFromNode(XmlNode node, string attributeName)
        {
            string result = string.Empty;

            if (node.Attributes[attributeName] != null)
            {
                //Attribute has an value return that.
                result = node.Attributes[attributeName].InnerText;
            }
            return result;
        }

    }
}
